package org.linlinjava.litemall.admin.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.linlinjava.litemall.admin.vo.formulamaterial.FormulaMaterialMultipleRespVO;
import org.linlinjava.litemall.admin.vo.formulamaterial.FormulaMaterialRespVO;
import org.linlinjava.litemall.core.exception.util.ServiceExceptionUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.LitemallMerchandise;
import org.linlinjava.litemall.db.domain.LumiereFormulaMaterial;
import org.linlinjava.litemall.db.domain.LumiereFormulaSpecificationsDataProportioning;
import org.linlinjava.litemall.db.domain.LumiereMaterialClassification;
import org.linlinjava.litemall.db.service.LitemallMerchandiseService;
import org.linlinjava.litemall.db.service.LumiereFormulaMaterialService;
import org.linlinjava.litemall.db.service.LumiereFormulaSpecificationsDataProportioningService;
import org.linlinjava.litemall.db.service.LumiereMaterialClassificationService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import static org.linlinjava.litemall.admin.errorcode.ErrorCodeConstants.LUMIERE_FORMULA_FORMULA_MATERIAL_EXIST;

/**
 * @auth :ply
 * @date 2024/5/16 10:40
 * @Description TODO
 * 管理配方原料管理服务
 */
@Service
@RequiredArgsConstructor
public class AdminLumiereFormulaMaterialService {

    private final LumiereFormulaMaterialService lumiereFormulaMaterialService;

    private final LumiereMaterialClassificationService lumiereMaterialClassificationService;
    private final LitemallMerchandiseService litemallMerchandiseService;

    private final LumiereFormulaSpecificationsDataProportioningService lumiereFormulaSpecificationsDataProportioningService;

    /**
     * 根据查询条件查询配方原料列表
     * @param lumiereFormulaMaterial 查询条件
     * @param page 当前页数，默认为1
     * @param limit 每页数量，默认为10
     * @return 配方原料列表
     */
    public ResponseUtil.Response listLumiereFormulaMaterial(LumiereFormulaMaterial lumiereFormulaMaterial,
                                                            Integer page,
                                                            Integer limit) {
        // 构建查询条件
        LambdaQueryWrapper<LumiereFormulaMaterial> queryWrapper = new LambdaQueryWrapper<>();
        Optional.ofNullable(lumiereFormulaMaterial.getFormulaId())
                .filter(id -> id != 0) // 判断formulaId是否不等于0
                .ifPresent(id -> queryWrapper.eq(LumiereFormulaMaterial::getFormulaId, id));

        Optional.ofNullable(lumiereFormulaMaterial.getMaterialName())
                .filter(StringUtils::isNotEmpty)
                .ifPresent(name -> queryWrapper.like(LumiereFormulaMaterial::getMaterialName, name));
        queryWrapper.eq(StrUtil.isNotEmpty(lumiereFormulaMaterial.getMaterialClassificationName()),LumiereFormulaMaterial::getMaterialClassificationName, lumiereFormulaMaterial.getMaterialClassificationName());

        queryWrapper.orderByAsc(LumiereFormulaMaterial::getMaterialClassificationName);

        queryWrapper.orderByDesc(LumiereFormulaMaterial::getAddTime);
        // 执行查询
        IPage<LumiereFormulaMaterial> resultList = lumiereFormulaMaterialService.page(new Page<>(page,limit),queryWrapper);
        //return ResponseUtil.okList(resultList);
        List formulaMaterialRespVOList = CollStreamUtil.toList(resultList.getRecords(), formulaMaterial -> {
            LumiereMaterialClassification materialClassification = lumiereMaterialClassificationService.getByClassification(formulaMaterial.getMaterialClassificationName());
            FormulaMaterialRespVO formulaMaterialRespVO = BeanUtil.toBean(formulaMaterial, FormulaMaterialRespVO.class)
                    .setClassificationName(materialClassification!=null?materialClassification.getClassificationName():null).setClassificationColour(materialClassification!=null?materialClassification.getClassificationColour():null);
            //基础原料表信息 拷贝
            LitemallMerchandise merchandise = litemallMerchandiseService.getById(formulaMaterialRespVO.getMaterialId());
            formulaMaterialRespVO.setLabel(merchandise.getLabel());
            formulaMaterialRespVO.setBrand(merchandise.getBrand());
            formulaMaterialRespVO.setMerchandiseSn(merchandise.getMerchandiseSn());
            formulaMaterialRespVO.setSellingPrice(merchandise.getSellingPrice());
            formulaMaterialRespVO.setPurchasePrice(merchandise.getPurchasePrice());
            formulaMaterialRespVO.setNumber(merchandise.getNumber());
            formulaMaterialRespVO.setBasicUnit(merchandise.getBasicUnit());
            formulaMaterialRespVO.setCheckUnit(merchandise.getCheckUnit());
            formulaMaterialRespVO.setCheckRatio(merchandise.getCheckRatio());
            formulaMaterialRespVO.setRatio(merchandise.getRatio());
            formulaMaterialRespVO.setModel(merchandise.getModel());
            formulaMaterialRespVO.setStandard(merchandise.getStandard());
            formulaMaterialRespVO.setProperty(merchandise.getProperty());
            return formulaMaterialRespVO;
        });
        // 返回结果
        resultList.setRecords(formulaMaterialRespVOList);
        return ResponseUtil.okPage(resultList);
    }

    /**
     * 根据查询条件查询配方原料列表
     * @return 配方原料列表
     */
    public ResponseUtil.Response listAllLumiereFormulaMaterial() {

        // 构建查询条件
        LambdaQueryWrapper<LumiereFormulaMaterial> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(LumiereFormulaMaterial::getAddTime);
        // 执行查询
        List<LumiereFormulaMaterial> resultList = lumiereFormulaMaterialService.list(queryWrapper);

        List<FormulaMaterialRespVO> formulaMaterialRespVOList = CollStreamUtil.toList(resultList, formulaMaterial -> {
            FormulaMaterialRespVO formulaMaterialRespVO = BeanUtil.toBean(formulaMaterial, FormulaMaterialRespVO.class);
            //基础原料表信息 拷贝
            LitemallMerchandise merchandise = litemallMerchandiseService.getById(formulaMaterialRespVO.getMaterialId());
            formulaMaterialRespVO.setLabel(merchandise.getLabel());
            formulaMaterialRespVO.setBrand(merchandise.getBrand());
            formulaMaterialRespVO.setMerchandiseSn(merchandise.getMerchandiseSn());
            formulaMaterialRespVO.setSellingPrice(merchandise.getSellingPrice());
            formulaMaterialRespVO.setPurchasePrice(merchandise.getPurchasePrice());
            formulaMaterialRespVO.setNumber(merchandise.getNumber());
            formulaMaterialRespVO.setBasicUnit(merchandise.getBasicUnit());
            formulaMaterialRespVO.setCheckUnit(merchandise.getCheckUnit());
            formulaMaterialRespVO.setCheckRatio(merchandise.getCheckRatio());
            formulaMaterialRespVO.setRatio(merchandise.getRatio());
            formulaMaterialRespVO.setModel(merchandise.getModel());
            formulaMaterialRespVO.setStandard(merchandise.getStandard());
            formulaMaterialRespVO.setProperty(merchandise.getProperty());
            return formulaMaterialRespVO;
        });
        // 返回结果
        return ResponseUtil.ok(formulaMaterialRespVOList);
    }

    /*public ResponseUtil.Response listMultipleLumiereFormulaMaterial(FormulaMaterialMultipleRespVO materialMultipleRespVO) {

        LumiereMaterialClassification materialClassification = lumiereMaterialClassificationService.getById(materialMultipleRespVO.getMaterialClassificationId());
        // 构建查询条件
        LambdaQueryWrapper<LumiereFormulaMaterial> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LumiereFormulaMaterial::getMaterialClassificationName,materialClassification.getClassificationName());
        queryWrapper.orderByDesc(LumiereFormulaMaterial::getAddTime);
        // 所有原料
        List<LumiereFormulaMaterial> formulaMaterialList = lumiereFormulaMaterialService.list(queryWrapper);

        //当前规格下所有原料
        LambdaQueryWrapper<LumiereFormulaSpecificationsDataProportioning> specificationsDataProportioningLambdaQueryWrapper = new LambdaQueryWrapper<>();
        specificationsDataProportioningLambdaQueryWrapper.eq(LumiereFormulaSpecificationsDataProportioning::getFormulaSpecificationsId,materialMultipleRespVO.getFormulaSpecificationsId());
        List<LumiereFormulaSpecificationsDataProportioning> formulaSpecificationsDataProportioningList = lumiereFormulaSpecificationsDataProportioningService.list(specificationsDataProportioningLambdaQueryWrapper);
        Set<Integer> set = CollStreamUtil.toSet(formulaSpecificationsDataProportioningList, LumiereFormulaSpecificationsDataProportioning::getFormulaMaterialId);

        List<FormulaMaterialRespVO> formulaMaterialRespVOList = CollStreamUtil.toList(formulaMaterialList, formulaMaterial -> {
            FormulaMaterialRespVO formulaMaterialRespVO = BeanUtil.toBean(formulaMaterial, FormulaMaterialRespVO.class);
            //基础原料表信息 拷贝
            LitemallMerchandise merchandise = litemallMerchandiseService.getById(formulaMaterialRespVO.getMaterialId());
            formulaMaterialRespVO.setLabel(merchandise.getLabel());
            formulaMaterialRespVO.setBrand(merchandise.getBrand());
            formulaMaterialRespVO.setMerchandiseSn(merchandise.getMerchandiseSn());
            formulaMaterialRespVO.setSellingPrice(merchandise.getSellingPrice());
            formulaMaterialRespVO.setPurchasePrice(merchandise.getPurchasePrice());
            formulaMaterialRespVO.setNumber(merchandise.getNumber());
            formulaMaterialRespVO.setBasicUnit(merchandise.getBasicUnit());
            formulaMaterialRespVO.setCheckUnit(merchandise.getCheckUnit());
            formulaMaterialRespVO.setCheckRatio(merchandise.getCheckRatio());
            formulaMaterialRespVO.setRatio(merchandise.getRatio());
            formulaMaterialRespVO.setModel(merchandise.getModel());
            formulaMaterialRespVO.setStandard(merchandise.getStandard());
            formulaMaterialRespVO.setProperty(merchandise.getProperty());

            //存在就不可选择
            formulaMaterialRespVO.setDisabled(CollUtil.contains(set,formulaMaterial.getId()));
            return formulaMaterialRespVO;
        });

        // 返回结果
        return ResponseUtil.ok(formulaMaterialRespVOList);
    }*/

    public ResponseUtil.Response listMultipleLumiereFormulaMaterial(FormulaMaterialMultipleRespVO materialMultipleRespVO) {

        LumiereMaterialClassification materialClassification = lumiereMaterialClassificationService.getById(materialMultipleRespVO.getMaterialClassificationId());
        // 构建查询条件
        LambdaQueryWrapper<LumiereFormulaMaterial> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(LumiereFormulaMaterial::getMaterialClassificationName,materialClassification.getClassificationName());
        queryWrapper.orderByDesc(LumiereFormulaMaterial::getAddTime);
        // 所有原料
        List<LumiereFormulaMaterial> formulaMaterialList = lumiereFormulaMaterialService.list(queryWrapper);

        List<FormulaMaterialRespVO> formulaMaterialRespVOList = CollStreamUtil.toList(formulaMaterialList, formulaMaterial -> {
            FormulaMaterialRespVO formulaMaterialRespVO = BeanUtil.toBean(formulaMaterial, FormulaMaterialRespVO.class);
            //基础原料表信息 拷贝
            LitemallMerchandise merchandise = litemallMerchandiseService.getById(formulaMaterialRespVO.getMaterialId());
            formulaMaterialRespVO.setLabel(merchandise.getLabel());
            formulaMaterialRespVO.setBrand(merchandise.getBrand());
            formulaMaterialRespVO.setMerchandiseSn(merchandise.getMerchandiseSn());
            formulaMaterialRespVO.setSellingPrice(merchandise.getSellingPrice());
            formulaMaterialRespVO.setPurchasePrice(merchandise.getPurchasePrice());
            formulaMaterialRespVO.setNumber(merchandise.getNumber());
            formulaMaterialRespVO.setBasicUnit(merchandise.getBasicUnit());
            formulaMaterialRespVO.setCheckUnit(merchandise.getCheckUnit());
            formulaMaterialRespVO.setCheckRatio(merchandise.getCheckRatio());
            formulaMaterialRespVO.setRatio(merchandise.getRatio());
            formulaMaterialRespVO.setModel(merchandise.getModel());
            formulaMaterialRespVO.setStandard(merchandise.getStandard());
            formulaMaterialRespVO.setProperty(merchandise.getProperty());

            LambdaQueryWrapper<LumiereFormulaSpecificationsDataProportioning> specificationsDataProportioningLambdaQueryWrapper = new LambdaQueryWrapper<>();
            specificationsDataProportioningLambdaQueryWrapper.eq(LumiereFormulaSpecificationsDataProportioning::getFormulaSpecificationsId,materialMultipleRespVO.getFormulaSpecificationsId());
            specificationsDataProportioningLambdaQueryWrapper.eq(LumiereFormulaSpecificationsDataProportioning::getMaterialType,materialMultipleRespVO.getMaterialType());
            specificationsDataProportioningLambdaQueryWrapper.eq(LumiereFormulaSpecificationsDataProportioning::getFormulaMaterialId,formulaMaterial.getId());
            long count = lumiereFormulaSpecificationsDataProportioningService.count(specificationsDataProportioningLambdaQueryWrapper);
            formulaMaterialRespVO.setDisabled(count>0);
            if(materialMultipleRespVO.getGroupName()!=null){
                List<LumiereFormulaSpecificationsDataProportioning> formulaSpecificationsDataProportioningList = lumiereFormulaSpecificationsDataProportioningService.list(Wrappers.lambdaQuery(LumiereFormulaSpecificationsDataProportioning.class)
                        .eq(LumiereFormulaSpecificationsDataProportioning::getGroupName, materialMultipleRespVO.getGroupName()));
                Set<Integer> set = CollStreamUtil.toSet(formulaSpecificationsDataProportioningList, LumiereFormulaSpecificationsDataProportioning::getFormulaMaterialId);
                formulaMaterialRespVO.setDisabled(CollUtil.contains(set,formulaMaterial.getId()));
            }
            return formulaMaterialRespVO;
        });

        // 返回结果
        return ResponseUtil.ok(formulaMaterialRespVOList);
    }

    /**
     * 根据指定ID获取配方原料详情。
     * @param id 配方ID
     * @return 包含配方详情的响应结果
     */
    public ResponseUtil.Response details(Integer id){
        return ResponseUtil.ok(lumiereFormulaMaterialService.getById(id));
    }

    /**
     * 添加新的配方原料。
     * @param lumiereFormulaMaterial 待添加的配方原料对象
     * @return 添加操作的响应结果
     */
    public ResponseUtil.Response addLumiereFormulaMaterial(LumiereFormulaMaterial lumiereFormulaMaterial) {
        List<LumiereFormulaMaterial> formulaMaterials = lumiereFormulaMaterialService.list(Wrappers.lambdaQuery(LumiereFormulaMaterial.class).eq(LumiereFormulaMaterial::getMaterialName, lumiereFormulaMaterial.getMaterialName()));
        if(formulaMaterials.size()>0){
            throw ServiceExceptionUtil.exception(LUMIERE_FORMULA_FORMULA_MATERIAL_EXIST);
        }
        return lumiereFormulaMaterialService.save(lumiereFormulaMaterial) ? ResponseUtil.ok(lumiereFormulaMaterial.getId()) : ResponseUtil.fail();
    }

    /**
     * 更新配方原料信息。
     * @param lumiereFormulaMaterial 待更新的配方原料对象
     * @return 更新操作的响应结果
     */
    public ResponseUtil.Response updateLumiereFormulaMaterial(LumiereFormulaMaterial lumiereFormulaMaterial) {
        return lumiereFormulaMaterialService.updateById(lumiereFormulaMaterial) ? ResponseUtil.ok() : ResponseUtil.fail();
    }

    /**
     * 根据指定ID删除配方原料。
     * @param id 待删除的路配方原料ID
     * @return 删除操作的响应结果
     */
    public ResponseUtil.Response deleteLumiereFormulaMaterial(Integer id){
        //关联
        LambdaUpdateWrapper<LumiereFormulaSpecificationsDataProportioning> objectLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        objectLambdaUpdateWrapper.eq(LumiereFormulaSpecificationsDataProportioning::getFormulaMaterialId,id);
        objectLambdaUpdateWrapper.set(LumiereFormulaSpecificationsDataProportioning::getDeleted,1);
        lumiereFormulaSpecificationsDataProportioningService.update(objectLambdaUpdateWrapper);
        return lumiereFormulaMaterialService.removeById(id) ? ResponseUtil.ok() : ResponseUtil.fail();
    }


    @Transactional
    public void syncLumiereFormulaMaterial() {
        // 获取所有原料
        List<LitemallMerchandise> merchandiseList = litemallMerchandiseService.selectList(Wrappers.lambdaQuery(LitemallMerchandise.class));

        //统一插入
        List<LumiereFormulaMaterial> formulaMaterialList = new ArrayList<>();
        for (LitemallMerchandise merchandise : merchandiseList) {
            //id存在则更新 不存在就同步
            LumiereFormulaMaterial formulaMaterial = lumiereFormulaMaterialService.getOne(Wrappers.lambdaQuery(LumiereFormulaMaterial.class)
                    .eq(LumiereFormulaMaterial::getMaterialId, merchandise.getId()));
            if(formulaMaterial==null){
                formulaMaterial = new LumiereFormulaMaterial().setMaterialId(merchandise.getId())
                        .setMaterialName(merchandise.getName())
                        .setMaterialImg(merchandise.getPicUrl())
                        .setMaterialClassificationName(merchandise.getName()).setUnit(merchandise.getBasicUnit());
            }else {
                formulaMaterial.setMaterialId(merchandise.getId());
                formulaMaterial.setMaterialName(merchandise.getName());
                formulaMaterial.setMaterialImg(merchandise.getPicUrl());
                formulaMaterial.setMaterialClassificationName(merchandise.getName());
                formulaMaterial.setUnit(merchandise.getBasicUnit());
            }
            formulaMaterialList.add(formulaMaterial);
        }
        lumiereFormulaMaterialService.saveOrUpdateBatch(formulaMaterialList);
    }


}
